﻿#region Disclaimer/Info
///////////////////////////////////////////////////////////////////////////////////////////////////
// MetaCollection
// 
// MetaCollection is a system to provide a standard structure, permissions and metadata service
// for content organization.
//
// This project is hosted at Google Code at http://code.google.com/p/metacollection/
//
// This project is licensed under the BSD license.  See the License.txt file for more information.
///////////////////////////////////////////////////////////////////////////////////////////////////
#endregion


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MetaCollection.Framework.Helpers
{
	/// <summary>
	/// Borrowed and modified from http://stackoverflow.com/questions/35002/does-c-have-a-way-of-giving-me-an-immutable-dictionary
	/// according to rights granted under the cc-wiki license: http://creativecommons.org/licenses/by-sa/2.5/
	/// </summary>
	/// <typeparam name="TKey">The key type</typeparam>
	/// <typeparam name="TValue">The value type</typeparam>
	/// <exception cref="InvalidOperationException">Thrown if attempts to mutate dictionary are made.</exception>
	public class ReadOnlyDictionary<TKey, TValue> : IDictionary<TKey, TValue>
	{
		private IDictionary<TKey, TValue> _dict;

		public ReadOnlyDictionary(IDictionary<TKey, TValue> dictionary)
		{
			_dict = dictionary;
		}

		public void Add(TKey key, TValue value)
		{
			throw new InvalidOperationException();
		}

		public bool ContainsKey(TKey key)
		{
			return _dict.ContainsKey(key);
		}

		public ICollection<TKey> Keys
		{
			get { return _dict.Keys; }
		}

		public bool Remove(TKey key)
		{
			throw new InvalidOperationException();
		}

		public bool TryGetValue(TKey key, out TValue value)
		{
			return _dict.TryGetValue(key, out value);
		}

		public ICollection<TValue> Values
		{
			get { return _dict.Values; }
		}

		public TValue this[TKey key]
		{
			get { return _dict[key]; }
			set { throw new InvalidOperationException(); }
		}

		public void Add(KeyValuePair<TKey, TValue> item)
		{
			throw new InvalidOperationException();
		}

		public void Clear()
		{
			throw new InvalidOperationException();
		}

		public bool Contains(KeyValuePair<TKey, TValue> item)
		{
			return _dict.ContainsKey(item.Key);
		}

		public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
		{
			_dict.CopyTo(array, arrayIndex);
		}

		public int Count
		{
			get { return _dict.Count; }
		}

		public bool IsReadOnly
		{
			get { return true; }
		}

		public bool Remove(KeyValuePair<TKey, TValue> item)
		{
			throw new InvalidOperationException();
		}

		public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
		{
			return _dict.GetEnumerator();
		}

		System.Collections.IEnumerator
			   System.Collections.IEnumerable.GetEnumerator()
		{
			return ((System.Collections.IEnumerable)_dict).GetEnumerator();
		}
	}

}
